package cs575.wido.ui;

import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Collections;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class SuggestionBox extends JComboBox implements KeyListener {
	private boolean hide_flag;
	private final JTextField tf;
	private final DefaultComboBoxModel model;
	private final Vector<String> v;
	
	public SuggestionBox(Vector<String> suggestList) {
		this.hide_flag = false;
		this.model = new DefaultComboBoxModel();
		this.v = suggestList;
		
		this.setEditable(true);
		this.tf = (JTextField) this.getEditor().getEditorComponent();
		
		this.tf.addKeyListener(this);
	}

	private void setModel(DefaultComboBoxModel mdl, String str) {
		this.setModel(mdl);
		this.setSelectedIndex(-1);
		this.tf.setText(str);
	}
	
	private static DefaultComboBoxModel getSuggestedModel(
			java.util.List<String> list, String text) {
		DefaultComboBoxModel m = new DefaultComboBoxModel();
		for (String s : list) {
			if (s.startsWith(text))
				m.addElement(s);
		}
		return m;
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		String text = this.tf.getText();
		int code = e.getKeyCode();
		if (code == KeyEvent.VK_ENTER) {
			if (!v.contains(text)) {
				v.addElement(text);
				Collections.sort(v);
				setModel(getSuggestedModel(v, text), text);
			}
			hide_flag = true;
		} else if (code == KeyEvent.VK_ESCAPE) {
			hide_flag = true;
		} else if (code == KeyEvent.VK_RIGHT) {
			for (int i = 0; i < v.size(); i++) {
				String str = v.elementAt(i);
				if (str.startsWith(text)) {
					SuggestionBox.this.setSelectedIndex(-1);
					SuggestionBox.this.tf.setText(str);
					return;
				}
			}
		}		
	}

	@Override
	public void keyReleased(KeyEvent e) {
				
	}

	@Override
	public void keyTyped(KeyEvent e) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				String text = SuggestionBox.this.tf.getText();
				if (text.length() == 0) {
					SuggestionBox.this.hidePopup();
					setModel(new DefaultComboBoxModel(v), "");
				} else {
					DefaultComboBoxModel m = getSuggestedModel(v, text);
					if (m.getSize() == 0 || hide_flag) {
						SuggestionBox.this.hidePopup();
						hide_flag = false;
					} else {
						setModel(m, text);
						SuggestionBox.this.showPopup();
					}
				}
			}		
		});
	}
	
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		
		Vector<String> vector = new Vector<String>();
		vector.add("abc");
		vector.add("ac");
		vector.add("bc");
		
		frame.getContentPane().add(new SuggestionBox(vector));
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
}
